(function (win, doc) {
	function Modal(options) {
		var defaultOptions = {
			/** 
			 * modal选择器
			 */
			selector: '.modal',
			/** 
			 * mask选择器
			 */
			maskSelector: '.mask',
			/**
			 * 自动关闭毫秒数，设置0不会自动关闭
			 * 自动关闭不会触发confirm和cancel回调
			 */
			timeout: 0, 
			/**
			 * 自定义初始化回调，为modal中各控件添加事件，收集数据
			 * 回调中this指向该modal对象
			 * 操作的数据对象应该为this.data
			 * Note: 确认及取消按钮事件已经在内部绑定，不要再在该回调中重复绑定
			 * @example
			 *     function () {
			 *         this.data.id = 1;
			 *         this.data.xx = 'xx';
			 *     }
			 */
			process: null, 
			/**
			 * 打开前回调，自定义一些modal打开前的操作
			 * 回调中this指向该modal对象
			 */
			open: null, 
			/** 
			 * 确定回调
			 * @param {object} [data] 收集的数据this.data
			 * @example
			 *     function (data) {
			 *         if (data.id === 1) {
			 *             // do something
			 *         }
			 *     }
			 */
			confirm: null, 
			/**
			 * 取消回调，参数及调用方式同confirm
			 * @param {object} [data] 收集的数据this.data
			 */
			cancel: null
		};
		this.options = extend(defaultOptions, options);
		this.container = doc.querySelector(this.options.selector);
		this.mask = doc.querySelector(this.options.maskSelector);
		this.data = {};
		this.isOpen = false;

		this.init();
	}
	Modal.prototype = {
		init: function () {
			var self = this,
				handler = this.options.process,
				btns = this.container.querySelectorAll('.modal-footer a');
			if (handler && isFunction(handler)) {
				handler.call(this);
			}
			if (btns[0]) {
				//  取消按钮
				btns[0].addEventListener('click', function () {
					self.cancel(self.data);
				});
			}
			if (btns[1]) {
				// 确认按钮
				btns[1].addEventListener('click', function () {
					self.confirm(self.data);
				});
			}
			this.container.addEventListener('touchmove', function (e) {
				e.preventDefault();
			});
		},
		open: function () {
			var self = this;
			var handler;
			if (this.isOpen) {
				return;
			}
			handler = this.options.open;
			if (handler && isFunction(handler)) {
				handler.call(this);
			}
			this.container.classList.remove('hide');
			this.mask.classList.remove('hide');
			this.isOpen = true;
			if (this.options.timeout > 0) {
				setTimeout(function () {
					self.close();
				}, this.options.timeout);
			}
		},
		confirm: function () {
			var handler = this.options.confirm;
			this.close();
			if (handler && isFunction(handler)) {
				handler(this.data);
			}
		},
		cancel: function () {
			var handler = this.options.cancel;
			this.close();
			if (handler && isFunction(handler)) {
				handler(this.data);
			}
		},
		close: function () {
			if (!this.isOpen) {
				return;
			}
			this.container.classList.add('hide');
			this.mask.classList.add('hide');
			this.isOpen = false;
		},
		reset: function () {
			this.data = {};
		}
	};

	function isFunction(target) {
		return typeof target === 'function';
	}

	function extend(target, source) {
		var k;
		target = target || {};
		for (k in source) {
			target[k] = source[k];
		}
		return target;
	}
	win.Modal = Modal;
}(window, document));
